/*   1:    */ package com.atomikos.icatch.imp;
/*   2:    */ 
/*   3:    */ import com.atomikos.icatch.CompositeTransaction;
/*   4:    */ import com.atomikos.icatch.Extent;
/*   5:    */ import com.atomikos.icatch.HeurCommitException;
/*   6:    */ import com.atomikos.icatch.HeurHazardException;
/*   7:    */ import com.atomikos.icatch.HeurMixedException;
/*   8:    */ import com.atomikos.icatch.Participant;
/*   9:    */ import com.atomikos.icatch.RecoveryCoordinator;
/*  10:    */ import com.atomikos.icatch.RollbackException;
/*  11:    */ import com.atomikos.icatch.StringHeuristicMessage;
/*  12:    */ import com.atomikos.icatch.SubTxAwareParticipant;
/*  13:    */ import com.atomikos.icatch.Synchronization;
/*  14:    */ import com.atomikos.icatch.SysException;
/*  15:    */ import com.atomikos.icatch.TransactionControl;
/*  16:    */ import com.atomikos.icatch.TxState;
/*  17:    */ import com.atomikos.icatch.system.Configuration;
/*  18:    */ import java.util.ArrayList;
/*  19:    */ import java.util.Enumeration;
/*  20:    */ import java.util.List;
/*  21:    */ import java.util.Stack;
/*  22:    */ 
/*  23:    */ abstract class TransactionStateHandler
/*  24:    */   implements SubTxAwareParticipant
/*  25:    */ {
/*  26:    */   private int subtxs_;
/*  27:    */   private Stack synchronizations_;
/*  28:    */   private List subtxawares_;
/*  29:    */   private CompositeTransactionImp ct_;
/*  30:    */   
/*  31:    */   protected TransactionStateHandler(CompositeTransactionImp ct)
/*  32:    */   {
/*  33: 70 */     this.ct_ = ct;
/*  34: 71 */     this.subtxs_ = 0;
/*  35: 72 */     this.subtxawares_ = new ArrayList();
/*  36:    */     
/*  37: 74 */     this.synchronizations_ = new Stack();
/*  38:    */   }
/*  39:    */   
/*  40:    */   protected TransactionStateHandler(CompositeTransactionImp ct, TransactionStateHandler handler)
/*  41:    */   {
/*  42: 80 */     this.subtxs_ = handler.getSubTransactionCount();
/*  43:    */     
/*  44: 82 */     this.synchronizations_ = handler.getSynchronizations();
/*  45: 83 */     this.subtxawares_ = handler.getSubtxawares();
/*  46: 84 */     this.ct_ = ct;
/*  47:    */   }
/*  48:    */   
/*  49:    */   private synchronized void localDecSubTxCount()
/*  50:    */   {
/*  51: 90 */     this.subtxs_ -= 1;
/*  52:    */   }
/*  53:    */   
/*  54:    */   private synchronized void localIncSubTxCount()
/*  55:    */   {
/*  56: 95 */     this.subtxs_ += 1;
/*  57:    */   }
/*  58:    */   
/*  59:    */   private synchronized int localGetSubTxCount()
/*  60:    */   {
/*  61:100 */     return this.subtxs_;
/*  62:    */   }
/*  63:    */   
/*  64:    */   private synchronized void localPushSynchronization(Synchronization sync)
/*  65:    */   {
/*  66:105 */     this.synchronizations_.push(sync);
/*  67:    */   }
/*  68:    */   
/*  69:    */   private synchronized void localAddSubTxAwareParticipant(SubTxAwareParticipant p)
/*  70:    */   {
/*  71:110 */     this.subtxawares_.add(p);
/*  72:    */   }
/*  73:    */   
/*  74:    */   protected CompositeTransaction createSubTransaction()
/*  75:    */     throws SysException, IllegalStateException
/*  76:    */   {
/*  77:117 */     CompositeTransaction ct = null;
/*  78:118 */     ct = this.ct_.getTransactionService().createSubTransaction(this.ct_);
/*  79:    */     
/*  80:120 */     ct.addSubTxAwareParticipant(this);
/*  81:121 */     localIncSubTxCount();
/*  82:122 */     return ct;
/*  83:    */   }
/*  84:    */   
/*  85:    */   protected RecoveryCoordinator addParticipant(Participant participant)
/*  86:    */     throws SysException, IllegalStateException
/*  87:    */   {
/*  88:131 */     CoordinatorImp coord = this.ct_.getCoordinatorImp();
/*  89:    */     try
/*  90:    */     {
/*  91:133 */       coord.addParticipant(participant);
/*  92:    */     }
/*  93:    */     catch (RollbackException e)
/*  94:    */     {
/*  95:136 */       throw new IllegalStateException("Transaction already rolled back");
/*  96:    */     }
/*  97:138 */     return coord;
/*  98:    */   }
/*  99:    */   
/* 100:    */   protected void registerSynchronization(Synchronization sync)
/* 101:    */     throws IllegalStateException, UnsupportedOperationException, SysException
/* 102:    */   {
/* 103:144 */     if (sync != null)
/* 104:    */     {
/* 105:    */       try
/* 106:    */       {
/* 107:146 */         this.ct_.getCoordinatorImp().registerSynchronization(sync);
/* 108:    */       }
/* 109:    */       catch (RollbackException e)
/* 110:    */       {
/* 111:148 */         throw new IllegalStateException("Transaction already rolled back");
/* 112:    */       }
/* 113:151 */       localPushSynchronization(sync);
/* 114:    */     }
/* 115:    */   }
/* 116:    */   
/* 117:    */   protected void addSubTxAwareParticipant(SubTxAwareParticipant subtxaware)
/* 118:    */     throws SysException, IllegalStateException
/* 119:    */   {
/* 120:160 */     localAddSubTxAwareParticipant(subtxaware);
/* 121:    */   }
/* 122:    */   
/* 123:    */   private void rollback()
/* 124:    */     throws IllegalStateException, SysException
/* 125:    */   {
/* 126:165 */     Stack errors = new Stack();
/* 127:167 */     for (int i = 0; i < this.subtxawares_.size(); i++)
/* 128:    */     {
/* 129:168 */       SubTxAwareParticipant subtxaware = (SubTxAwareParticipant)this.subtxawares_.get(i);
/* 130:    */       
/* 131:170 */       subtxaware.rolledback(this.ct_);
/* 132:    */     }
/* 133:177 */     Enumeration enumm = null;
/* 134:178 */     Extent extent = this.ct_.getExtent();
/* 135:179 */     if (extent != null)
/* 136:    */     {
/* 137:180 */       enumm = extent.getParticipants().elements();
/* 138:181 */       while (enumm.hasMoreElements())
/* 139:    */       {
/* 140:182 */         Participant part = (Participant)enumm.nextElement();
/* 141:    */         
/* 142:184 */         addParticipant(part);
/* 143:    */       }
/* 144:    */     }
/* 145:190 */     this.ct_.localSetTransactionStateHandler(new TxTerminatedStateHandler(this.ct_, this, false));
/* 146:    */     try
/* 147:    */     {
/* 148:196 */       this.ct_.getCoordinatorImp().rollback();
/* 149:    */     }
/* 150:    */     catch (HeurCommitException e)
/* 151:    */     {
/* 152:198 */       errors.push(e);
/* 153:199 */       throw new SysException("Unexpected error in rollback", errors);
/* 154:    */     }
/* 155:    */     catch (HeurMixedException e)
/* 156:    */     {
/* 157:201 */       errors.push(e);
/* 158:202 */       throw new SysException("Unexpected error in rollback", errors);
/* 159:    */     }
/* 160:    */     catch (HeurHazardException e)
/* 161:    */     {
/* 162:204 */       errors.push(e);
/* 163:205 */       throw new SysException("Unexpected error in rollback", errors);
/* 164:    */     }
/* 165:    */   }
/* 166:    */   
/* 167:    */   protected void rollbackWithStateCheck()
/* 168:    */     throws IllegalStateException, SysException
/* 169:    */   {
/* 170:214 */     this.ct_.localTestAndSetTransactionStateHandler(this, new TxTerminatingStateHandler(false, this.ct_, this));
/* 171:    */     
/* 172:216 */     rollback();
/* 173:    */   }
/* 174:    */   
/* 175:    */   protected void commit()
/* 176:    */     throws SysException, IllegalStateException, RollbackException
/* 177:    */   {
/* 178:231 */     Stack participants = null;
/* 179:232 */     Stack synchronizations = null;
/* 180:    */     
/* 181:    */ 
/* 182:235 */     this.ct_.localTestAndSetTransactionStateHandler(this, new TxTerminatingStateHandler(true, this.ct_, this));
/* 183:243 */     if (this.ct_.isLocalRoot())
/* 184:    */     {
/* 185:248 */       this.ct_.getCoordinatorImp().addTag(this.ct_.tag_);
/* 186:    */       
/* 187:250 */       Enumeration enumm = this.ct_.getExtent().getParticipants().elements();
/* 188:251 */       while (enumm.hasMoreElements())
/* 189:    */       {
/* 190:252 */         Participant part = (Participant)enumm.nextElement();
/* 191:253 */         addParticipant(part);
/* 192:    */       }
/* 193:    */     }
/* 194:262 */     if (this.subtxs_ > 0) {
/* 195:263 */       throw new IllegalStateException("active subtransactions exist");
/* 196:    */     }
/* 197:273 */     Synchronization sync = null;
/* 198:274 */     Enumeration enumm = this.synchronizations_.elements();
/* 199:275 */     while (enumm.hasMoreElements())
/* 200:    */     {
/* 201:276 */       sync = (Synchronization)enumm.nextElement();
/* 202:    */       try
/* 203:    */       {
/* 204:278 */         sync.beforeCompletion();
/* 205:    */       }
/* 206:    */       catch (RuntimeException error)
/* 207:    */       {
/* 208:281 */         setRollbackOnly();
/* 209:282 */         Configuration.logWarning("Unexpected error in beforeCompletion: ", error);
/* 210:    */       }
/* 211:    */     }
/* 212:286 */     if (this.ct_.getState().equals(TxState.MARKED_ABORT))
/* 213:    */     {
/* 214:289 */       rollback();
/* 215:290 */       throw new RollbackException("The transaction was set to rollback only");
/* 216:    */     }
/* 217:295 */     for (int i = 0; i < this.subtxawares_.size(); i++)
/* 218:    */     {
/* 219:296 */       SubTxAwareParticipant subtxaware = (SubTxAwareParticipant)this.subtxawares_.get(i);
/* 220:    */       
/* 221:298 */       subtxaware.committed(this.ct_);
/* 222:    */     }
/* 223:306 */     this.ct_.localSetTransactionStateHandler(new TxTerminatedStateHandler(this.ct_, this, true));
/* 224:    */   }
/* 225:    */   
/* 226:    */   protected void setRollbackOnly()
/* 227:    */   {
/* 228:315 */     StringHeuristicMessage msg = new StringHeuristicMessage("Transaction.setRollbackOnly was called.");
/* 229:    */     
/* 230:317 */     RollbackOnlyParticipant p = new RollbackOnlyParticipant(msg);
/* 231:    */     try
/* 232:    */     {
/* 233:320 */       addParticipant(p);
/* 234:    */     }
/* 235:    */     catch (IllegalStateException alreadyTerminated)
/* 236:    */     {
/* 237:324 */       if (Configuration.isDebugLoggingEnabled()) {
/* 238:324 */         Configuration.logDebug("Error during setRollbackOnly", alreadyTerminated);
/* 239:    */       }
/* 240:    */     }
/* 241:326 */     synchronized (this)
/* 242:    */     {
/* 243:327 */       this.ct_.localSetTransactionStateHandler(new TxRollbackOnlyStateHandler(this.ct_, this));
/* 244:    */     }
/* 245:    */   }
/* 246:    */   
/* 247:    */   public void committed(CompositeTransaction subtx)
/* 248:    */   {
/* 249:335 */     CompositeTransactionImp ct = (CompositeTransactionImp)subtx;
/* 250:336 */     Extent toAdd = subtx.getTransactionControl().getExtent();
/* 251:337 */     Extent target = this.ct_.getExtent();
/* 252:338 */     target.add(toAdd);
/* 253:    */     
/* 254:    */ 
/* 255:    */ 
/* 256:    */ 
/* 257:    */ 
/* 258:    */ 
/* 259:345 */     SubTransactionCoordinatorParticipant part = new SubTransactionCoordinatorParticipant(ct.getCoordinatorImp());
/* 260:    */     
/* 261:347 */     addParticipant(part);
/* 262:    */     
/* 263:    */ 
/* 264:    */ 
/* 265:351 */     localDecSubTxCount();
/* 266:    */   }
/* 267:    */   
/* 268:    */   public void rolledback(CompositeTransaction subtx)
/* 269:    */   {
/* 270:356 */     localDecSubTxCount();
/* 271:    */   }
/* 272:    */   
/* 273:    */   protected abstract Object getState();
/* 274:    */   
/* 275:    */   protected List getSubtxawares()
/* 276:    */   {
/* 277:367 */     return this.subtxawares_;
/* 278:    */   }
/* 279:    */   
/* 280:    */   protected CompositeTransactionImp getCT()
/* 281:    */   {
/* 282:372 */     return this.ct_;
/* 283:    */   }
/* 284:    */   
/* 285:    */   protected int getSubTransactionCount()
/* 286:    */   {
/* 287:380 */     return localGetSubTxCount();
/* 288:    */   }
/* 289:    */   
/* 290:    */   protected Stack getSynchronizations()
/* 291:    */   {
/* 292:388 */     return this.synchronizations_;
/* 293:    */   }
/* 294:    */   
/* 295:    */   protected void addSynchronizations(Stack synchronizations)
/* 296:    */   {
/* 297:393 */     while (!synchronizations.empty())
/* 298:    */     {
/* 299:394 */       Synchronization next = (Synchronization)synchronizations.pop();
/* 300:395 */       localPushSynchronization(next);
/* 301:    */     }
/* 302:    */   }
/* 303:    */ }


/* Location:           C:\myfile\mysoft\apache-maven-3.5.0-bin\apache-maven-3.5.0\myrep\com\atomikos\transactions\3.7.0\transactions-3.7.0.jar
 * Qualified Name:     com.atomikos.icatch.imp.TransactionStateHandler
 * JD-Core Version:    0.7.0.1
 */